package bbs.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import bbs.entity.config.WebConfig;
import bbs.entity.constants.Constants;
import bbs.entity.dto.SessionWebUserDto;
import bbs.entity.enums.*;
import bbs.entity.po.*;
import bbs.entity.query.*;
import bbs.exception.BusinessException;
import bbs.mappers.*;
import bbs.service.EmailCodeService;
import bbs.service.UserMessageService;
import bbs.utils.FileUtil;
import bbs.utils.OKHttpUtils;
import bbs.utils.SysCacheUtils;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import bbs.entity.vo.PaginationResultVO;
import bbs.service.UserInfoService;
import bbs.utils.StringTools;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;


/**
 * 用户信息 业务接口实现
 */
@Service("userInfoService")
public class UserInfoServiceImpl implements UserInfoService {

	private static Logger logger = LoggerFactory.getLogger(UserInfoServiceImpl.class);

	@Resource
	private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;

	@Resource
	private EmailCodeService emailCodeService;

	@Resource
	private UserIntegralRecordMapper<UserIntegralRecord, UserIntegralRecordQuery> userIntegralRecordMapper;

	@Resource
	private UserMessageMapper<UserMessage, UserMessageQuery> userMessageMapper;

	@Resource
	private WebConfig webConfig;

	@Resource
	private FileUtil fileUtils;

	@Resource
	private ForumArticleMapper<ForumArticle, ForumArticleQuery> forumArticleMapper;

	@Resource
	private ForumCommentMapper<ForumComment, ForumCommentQuery> forumCommentMapper;

	@Resource
	private UserMessageService userMessageService;

	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<UserInfo> findListByParam(UserInfoQuery param) {
		return this.userInfoMapper.selectList(param);
	}

	/**
	 * 根据条件查询列表
	 */
	@Override
	public Integer findCountByParam(UserInfoQuery param) {
		return this.userInfoMapper.selectCount(param);
	}

	/**
	 * 分页查询方法
	 */
	@Override
	public PaginationResultVO<UserInfo> findListByPage(UserInfoQuery param) {
		int count = this.findCountByParam(param);
		int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

		SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
		param.setSimplePage(page);
		List<UserInfo> list = this.findListByParam(param);
		PaginationResultVO<UserInfo> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(UserInfo bean) {
		return this.userInfoMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<UserInfo> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.userInfoMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或者修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<UserInfo> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.userInfoMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 多条件更新
	 */
	@Override
	public Integer updateByParam(UserInfo bean, UserInfoQuery param) {
		StringTools.checkParam(param);
		return this.userInfoMapper.updateByParam(bean, param);
	}

	/**
	 * 多条件删除
	 */
	@Override
	public Integer deleteByParam(UserInfoQuery param) {
		StringTools.checkParam(param);
		return this.userInfoMapper.deleteByParam(param);
	}

	/**
	 * 根据UserId获取对象
	 */
	@Override
	public UserInfo getUserInfoByUserId(String userId) {
		return this.userInfoMapper.selectByUserId(userId);
	}

	/**
	 * 根据UserId修改
	 */
	@Override
	public Integer updateUserInfoByUserId(UserInfo bean, String userId) {
		return this.userInfoMapper.updateByUserId(bean, userId);
	}

	/**
	 * 根据UserId删除
	 */
	@Override
	public Integer deleteUserInfoByUserId(String userId) {
		return this.userInfoMapper.deleteByUserId(userId);
	}

	/**
	 * 根据Email获取对象
	 */
	@Override
	public UserInfo getUserInfoByEmail(String email) {
		return this.userInfoMapper.selectByEmail(email);
	}

	/**
	 * 根据Email修改
	 */
	@Override
	public Integer updateUserInfoByEmail(UserInfo bean, String email) {
		return this.userInfoMapper.updateByEmail(bean, email);
	}

	/**
	 * 根据Email删除
	 */
	@Override
	public Integer deleteUserInfoByEmail(String email) {
		return this.userInfoMapper.deleteByEmail(email);
	}

	/**
	 * 根据NickName获取对象
	 */
	@Override
	public UserInfo getUserInfoByNickName(String nickName) {
		return this.userInfoMapper.selectByNickName(nickName);
	}

	/**
	 * 根据NickName修改
	 */
	@Override
	public Integer updateUserInfoByNickName(UserInfo bean, String nickName) {
		return this.userInfoMapper.updateByNickName(bean, nickName);
	}

	/**
	 * 根据NickName删除
	 */
	@Override
	public Integer deleteUserInfoByNickName(String nickName) {
		return this.userInfoMapper.deleteByNickName(nickName);
	}

	/**
	 * 用户注册
	 * @param email
	 * @param nickName
	 * @param password
	 * @param emailCode
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void register(String email, String nickName, String password, String emailCode) {
		UserInfo userInfo = userInfoMapper.selectByEmail(email);

		if (userInfo != null) {
			throw new RuntimeException(Constants.EMAIL_EXISTS);
		}
		userInfo = userInfoMapper.selectByNickName(nickName);
		if (userInfo != null) {
			throw new RuntimeException(Constants.NICKNAME_EXISTS);
		}

		emailCodeService.checkEmailCode(email, emailCode);

		String userId = StringTools.getRandomNumber(Constants.LENGTH_10);

//		构建用户信息
		UserInfo insertInfo = new UserInfo();
		insertInfo.setUserId(userId);
		insertInfo.setEmail(email);
		insertInfo.setNickName(nickName);
		insertInfo.setPassword(StringTools.encodeMd5(password));
		insertInfo.setJoinTime(new Date());
		insertInfo.setStatus(UserStatusEnum.ENABLE.getStatus());
		insertInfo.setTotalIntegral(Constants.ZERO);
		insertInfo.setCurrentIntegral(Constants.ZERO);
		userInfoMapper.insert(insertInfo);

//		更新用户积分
		updateUserInternal(userId, UserIntegralOperTypeEnum.REGISTER, UserIntegralChangeTypeEnum.ADD.getChangeType(), Constants.LENGTH_5);
//		记录消息
		UserMessage message = new UserMessage();
		message.setReceivedUserId(userId);
		message.setMessageType(MessageTypeEnum.SYS.getType());
		message.setCreateTime(new Date());
		message.setStatus(MessageStatusEnum.UNREAD.getStatus());
		message.setMessageContent(SysCacheUtils.getSysSetting().getRegisterSetting().getRegisterWelcomInfo());
		userMessageMapper.insert(message);
	}

	/**
	 * 更新用户积分
	 * @param userId
	 * @param operType
	 * @param changeType
	 * @param integral
	 */
	@Transactional(rollbackFor = Exception.class)
	public void updateUserInternal(String userId, UserIntegralOperTypeEnum operType, Integer changeType, Integer integral) {
		integral = integral * changeType;
		if (integral == 0) return;
		UserInfo userInfo = userInfoMapper.selectByUserId(userId);
//		判断积分是否为负
		if (
			UserIntegralChangeTypeEnum.REDUCE.getChangeType().equals(changeType) &&
			userInfo.getCurrentIntegral() + integral < 0
		) {
			integral = changeType + userInfo.getCurrentIntegral();
		}

		UserIntegralRecord record = new UserIntegralRecord();
		record.setUserId(userId);
		record.setOperType(operType.getOperType());
		record.setIntegral(integral);
		record.setCreateTime(new Date());
		userIntegralRecordMapper.insert(record);

		Integer count = userInfoMapper.updateIntegral(userId, integral);
		if (count == 0) {
			throw new BusinessException(Constants.INTEGRAL_UPDATE_ERROR);
		}
	}

	/**
	 * 获取用户登录信息
	 * @param email
	 * @param password
	 * @param ip
	 * @return
	 */
    @Override
    public SessionWebUserDto login(String email, String password, String ip) {
		UserInfo userInfo = userInfoMapper.selectByEmail(email);
//		验证邮箱与是否匹配
		if (userInfo == null || !userInfo.getPassword().equals(password)) {
			throw new BusinessException(Constants.EMAIL_PASSWORD_ERROR);
		}
//		验证账号是否被封禁
		if (!UserStatusEnum.ENABLE.getStatus().equals(userInfo.getStatus())) {
			throw new BusinessException(Constants.ACCOUNT_DISABLE);
		}

//		记录登录信息
		String ipAddress = getIpAddresses();
		UserInfo updateInfo = new UserInfo();
		updateInfo.setLastLoginIp(ip);
		updateInfo.setLastLoginIpAddress(ipAddress);
		updateInfo.setLastLoginTime(new Date());
		updateInfo.setEmail(email);
		Integer i = userInfoMapper.updateByEmail(updateInfo, email);
		logger.info("更新地址成功：{}", i);

//		检查用户身份
		SessionWebUserDto sessionWebUserDto = new SessionWebUserDto();
		sessionWebUserDto.setNickName(updateInfo.getNickName());
		sessionWebUserDto.setUserId(userInfo.getUserId());
		sessionWebUserDto.setProvince(ipAddress);
		if (!StringTools.isEmpty(webConfig.getAdminEmails()) && ArrayUtils.contains(webConfig.getAdminEmails().split(","), userInfo.getEmail()))
		{
			sessionWebUserDto.setIsAdmin(true);
		}else {
			sessionWebUserDto.setIsAdmin(false);
		}

		return sessionWebUserDto;
    }

	/**
	 * 重置密码
	 * @param email
	 * @param password
	 * @param emailCode
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void resetPwd(String email, String password, String emailCode) {
		UserInfo userInfo = userInfoMapper.selectByEmail(email);
		if (userInfo == null) throw new BusinessException(Constants.EMAIL_NOT_EXISTS);
		emailCodeService.checkEmailCode(email, emailCode);

		UserInfo updateInfo = new UserInfo();
		updateInfo.setPassword(StringTools.encodeMd5(password));
		userInfoMapper.updateByEmail(updateInfo, email);
	}

	@Override
	public void updateUSerInfo(UserInfo userInfo, MultipartFile avatar) {
		userInfoMapper.updateByUserId(userInfo, userInfo.getUserId());
		if (avatar != null) {
			fileUtils.uploadFile2Local(avatar, userInfo.getUserId(), FileUploadTypeEnum.AVATAR);
		}
	}

    @Override
    public void updateUserStatus(Integer status, String userId) {
		if (UserStatusEnum.DISABLE.getStatus().equals(status)) {
			forumArticleMapper.updateStatusBatchByUserId(status, userId);
			forumCommentMapper.updateStatusBatchByUserId(status, userId);
		}
		UserInfo userInfo = new UserInfo();
		userInfo.setStatus(status);
		userInfoMapper.updateByUserId(userInfo, userId);
    }

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void sendMessage(String msg, String userId, Integer integral) {
		UserMessage message = new UserMessage();
		message.setReceivedUserId(userId);
		message.setMessageType(MessageTypeEnum.SYS.getType());
		message.setCreateTime(new Date());
		message.setStatus(MessageStatusEnum.UNREAD.getStatus());
		message.setMessageContent(msg);
		userMessageService.add(message);

		UserIntegralChangeTypeEnum userIntegralChangeTypeEnum = UserIntegralChangeTypeEnum.ADD;
		if (integral != null && integral != 0) {
			if (integral < 0) {
				integral = integral * -1;
				userIntegralChangeTypeEnum = UserIntegralChangeTypeEnum.REDUCE;
			}
			updateUserInternal(userId, UserIntegralOperTypeEnum.ADMIN, userIntegralChangeTypeEnum.getChangeType(), integral);
		}
	}


	public String getIpAddresses() {
		try {
			String url = "https://whois.pconline.com.cn/ipJson.jsp?json=true&ip=";
			String responseJson = OKHttpUtils.getRequest(url);
			if (responseJson == null) {
				return Constants.NO_ADDRESS;
			}

			// 使用 Gson 解析 JSON
			Gson gson = new Gson();
			JsonObject jsonObject = gson.fromJson(responseJson, JsonObject.class);

			// 提取所需数据
			String pro = jsonObject.get("pro").getAsString();
//			String city = jsonObject.get("city").getAsString();

			// 返回省份信息
			return pro;

		} catch (Exception e) {
			logger.error("获取IP地址信息失败", e);
		}
		return Constants.NO_ADDRESS;
	}


}